ついにブロックができるようになった!Amazon GuardDuty Malware Protection for Amazon S3が発表されました! #AWSreInforce
こんにちは、臼田です。
みなさん、AWS上でのマルウェアチェックしてますか?(挨拶
AWS re:Inforce 2024で待望のS3に対するネイティブなマルウェア検出と保護の機能である「Amazon GuardDuty Malware Protection for Amazon S3」がリリースされました!
Detect malware in new object uploads to Amazon S3 with Amazon GuardDuty - AWS
概要
Amazon GuardDutyはAWS上の様々な脅威を検出するサービスです。
EC2/IAM/S3に関する不審な挙動の検出から始まり、コンテナ環境やRDSやLambdaでの不審なアクティビティも検出したりします。更に、EC2に対しては不審な挙動を検出したら実際にEC2内部(つまりEBS)にマルウェアが含まれていないかスキャンすることが可能でした。
今回のアップデートでは、このマルウェアスキャンがS3に対しても実行できるようになりました。ちなみにS3のオブジェクトは350兆もあるようです!
しかし、ただスキャンができるだけではありません。より様々な環境でこのマルウェア保護の機能を導入できるんです!
従来のGuardDutyは脅威の「検出」を行ってきていました。つまりなにか危ないことが起きていたらそれを知ることができるんですね。マネージドで有効化するだけで様々な脅威が検出できるため導入も簡単で素晴らしいのですが、残念ながら検出した脅威をブロック(保護)することはできませんでした。
今回のS3に対するマルウェア保護では、スキャンしたあとにS3にタグを付けて、マルウェアであった場合にはバケットポリシーでそのタグのついたオブジェクトに対するアクセス制御を組み込むことで「マルウェアへアクセスすることを禁止」することが可能です。つまりブロックできるんです!
これまで検出だけだったGuardDutyがブロックまでできるようになったんです!これはもう親の気持ちですね…感慨深いです。娘も大きくなったなぁという気持ちです。
しかもそれだけではありません。今回の機能はこれまでの「オプション」の機能とは異なります。従来はAmazon GaurdDutyはAWS環境全体を保護する機能であったため、全体で有効化しつつオプションを追加していました。
S3のマルウェア保護は従来のGuardDutyの有効化とは独立して、個別に有効にすることが可能な機能です。つまり、アプリケーションの要件に合わせて必要な箇所だけにS3のマルウェア保護を導入できます。素晴らしいですね!
このサービスは現時点で正式リリースです。
ちなみに、従来S3に対するサーバレスなマルウェアスキャンを実行しようとしたら、Trend MicroのCloud One File Strage Security(C1FSS)が代表的な選択肢でした。
今回のアップデートで、ネイティブなS3のマルウェア保護ができるため、有力な選択肢の1つとなりました。
やってみた
Amazon GuardDuty Malware Protection for Amazon S3のユーザーガイドはこちら
残念ながらまだ画面が無いようだったので、更新され次第やってみます!
更新されたのでやっていきます!
GuardDuty有効化画面の変化
まず、GuardDutyが有効になっていないリージョンで確認します。すると以下のようにこれまでのGuardDutyの有効化画面と違って、S3のマルウェア保護だけ単体で利用する選択肢が出てきます。これがちがうところですね。
ただ今回は、通常のGuardDutyが有効の状態から始めていきます。ちなみに、どちらがおすすめですか?と聞かれたら間違いなく通常のGuardDutyも有効な状態で利用する方が良いです!なぜなら、検出した内容を画面上で詳細に確認したりできるからです。S3のマルウェア保護のみ利用する場合には、検出結果も出力されず、確認画面などはありません。検出したことを通知したり対応するためには個別にEventBridgeから受け取った通知を自身で処理する必要があるためです。
S3バケット準備
というわけでやっていきます。まず今回の検証用に新しくS3バケットを作成しておきます。暗号化設定はSSE-S3としました。ちなみにS3バケットのリージョンとGuardDutyのS3のマルウェア保護を有効化するリージョンは同一でなくてはいけません。
プランの作成
GuardDutyの画面ありでみていきましょう。左カラムの「保護プラン」の1つとして並んでいました。「有効にする」から進めます。
まずS3バケットを選択するため「S3を参照」を押します。
リージョンが違うとここで出てこないので注意です。検索したりして選択します。
選択できました。場合によっては、バケット内の特定のプレフィックスに絞りたい場合もあると思いますが、5つまで追加できます。今回はすべてのオブジェクトで進めます。タグ付けオプションもありますが、よっぽどタグを使っていない限りはつけるべきでしょう。
続いて、S3のマルウェア保護に利用するIAM Roleを選択します。既存のGuardDutyのRoleと別で独自のRoleが必要になるんですね。まあS3のデータを読む必要がありますから、他のものと分けて定義していくべきでしょう。保護するS3毎に作成するのがベストプラクティスだと思います。
「アクセス許可を表示」を押すと、設定すべきポリシーが表示されます。
まずは許可ポリシーから。バケット名などの毎回変わるパラメータは先程のS3を選択した際にうまくやってくれています。が、もうちょっと調整が必要になります。とはいえ調整は後回しにして、まずコピーしておきます。
続いて信頼ポリシーも同様にコピーしておきます。ちらっと見えますが、サービスとしても新しい体系になっていますね。
ではIAM Roleを作成しに行きます。適切なサービスの選択肢などはないので、「カスタム信頼ポリシー」を選択して、先程の信頼ポリシーを貼り付けます。
ポリシーなどはアタッチせずに進め、名前は適当に、とはいえS3バケット毎作るので、それぞれのバケット名を入れておくと良いでしょう。S3のマルウェア保護ではplanと呼ばれるリソースを作成して、これがスキャンをするため、私はs3バケット名-guardduty-plan-roleのようにしました。
作成したらインラインポリシーを作成します。
先程コピーした許可ポリシーを貼り付けつつ、S3の暗号化設定に合わせた調整を行います。KMS keyを選択している場合はそのIDを置き換え、SSE-S3の場合にはこのステートメントをまるっと削除します。削除するときはjsonのフォーマット通りに、手前のカンマ削除をお忘れなく。
IAMの設定が完了したら戻ってきて右のリロードを押し、IAM Roleを選択します。そしてプランを作成します。
作成完了しました。詳細画面も見ていきましょう。
下の方にCloudWatchのメトリクスが表示されています。これは嬉しいですね。
マルウェアの検出
では検出させてみましょう。下記ブログにあるように、CloudShellからeicarをアップロードします。
アップできました。ちなみにプランの作成をした段階でテスト用のオブジェクトもアップされていますね。詳細画面からタグを確認します。
GuardDutyMalwareScanStatus: THREATS_FOUND
のタグが付与されていました!
メトリクスでもカウントされていることが確認できます。
GuardDutyのFindingとしてはObject:S3/MaliciousFile
というタイプで検出されました。
詳細では、EICARファイルだよーなどの説明があります。
メインで見る部分は、S3オブジェクトの詳細、とくにマルウェアとしてはハッシュをマルウェアのDBに照会したりするのに使ったり、脅威名などを確認していくと思います。
いい感じですね!
マルウェアからの保護(ブロック)
さて、ここからが本番です!いつものGuardDutyなら検出できて良かったね。ですが今回はブロックもしていきます。
S3のバケットポリシーを利用してタグベースのアクセスコントロール(TBAC、つまりABAC)をしていきます。え、GuardDutyの機能じゃないじゃないかって?うるさいですね…。GuardDutyの機能でブロックができるようになったという概念が大切なんですよ!(暴論
詳細は下記のユーザーガイドにあります。が、これもちょっと注意が必要です。
S3 のマルウェア対策でタグベースのアクセス制御 (TBAC) を使用する - Amazon GuardDuty
原理としては、スキャン済みでかつマルウェアが検出されていないオブジェクトにのみアクセスを許可するというものです。
S3オブジェクトの状態としては、タグにGuardDutyMalwareScanStatus: NO_THREATS_FOUND
が追加されているもののみが許可される必要があります。先ほど作成したスキャン用のIAM Roleは例外とします。
ユーザーガイドにはタグ付けも制限するサンプルがありますが、今回は単純にしてブロックのみを実装します。以下のバケットポリシーをアタッチします。
{ "Version": "2012-10-17", "Statement": [ { "Sid": "NoReadExceptForClean", "Effect": "Deny", "NotPrincipal": { "AWS": [ "arn:aws:iam::999999999999:root", "arn:aws:iam::999999999999:role/malware-s3-tokyo-hogehoge-guardduty-plan-role", "arn:aws:sts::999999999999:assumed-role/malware-s3-tokyo-hogehoge-guardduty-plan-role/GuardDutyMalwareProtection" ] }, "Action": [ "s3:GetObject", "s3:GetObjectVersion" ], "Resource": [ "arn:aws:s3:::malware-s3-tokyo-hogehoge", "arn:aws:s3:::malware-s3-tokyo-hogehoge/*" ], "Condition": { "StringNotEquals": { "s3:ExistingObjectTag/GuardDutyMalwareScanStatus": "NO_THREATS_FOUND" } } } ] }
NotPrincipal
には、プランのIAM Roleとそのセッション、ついでにアカウント自体のプリンシパルを入れておく必要があります。
これでデータを取得してみましょう。CloudShellからeicarと、テスト用にアップされていたファイルを取得してみます。
[cloudshell-user@ip-10-132-82-115 ~]$ aws s3 cp s3://$S3/eicar.com ./ fatal error: An error occurred (403) when calling the HeadObject operation: Forbidden [cloudshell-user@ip-10-132-82-115 ~]$ aws s3 cp s3://$S3/malware-protection-resource-validation-object ./ download: s3://malware-s3-tokyo-fuga/malware-protection-resource-validation-object to ./malware-protection-resource-validation-object
無事にeicarだけブロックされましたね。
まとめ
GuardDutyで新しく実装されたS3のマルウェア保護を試してみました。
GuardDutyがブロックもできるのは感慨深いですね…
これまでのGuardDutyのスコープとは違い、個別のアプリケーション要件としてセキュリティを導入していく際に使う機能のため、信頼できないユーザーなどからのファイルアップロードを受け付けるシステムに導入していくと良いでしょう。ガンガン使いましょう!